<script setup lang="ts">
import { ActionBar, ActionBarButton, Dialog, Field, showFailToast, showToast } from 'vant'
import lodash from 'lodash'
import { ContactModel, MaterialModel, OrderModel } from '~/model'
import { Common } from '~/common'
import Api from '~/api'
import PairsView from '~/components/common/PairsView.vue'
import ContactPick from '~/components/order/edit/ContactPick.vue'
import DeliveryView from '~/components/order/DeliveryView.vue'
import { pickTime } from '~/utils'
import { OrderApi } from '~/api/OrderApi'

const route = useRoute()
const router = useRouter()

/**
 * 页面模式Enum：
 */
enum Mode {
  /** 无 */
  None,
  /**
   * 复制订单
   */
  Copy,
  /**
   * 编辑订单
   */
  Edit,
  FillUser, // 填充用户
}
/**
 * 页面模式对象
 */
const editMode = ref(Mode.None)

/**
 * 是否是新订单
 */
const isNew = computed(() => editMode.value !== Mode.Edit)

/**
 * 加载中
 */
// const loading = ref(true)

/**
 * 订单对象
 */
const order = ref(new OrderModel())
const originOrder = ref(new OrderModel())

/**
 * 直接watch order对象，无法获取变化之前的值(vue feature)
 * 创建一个对象对order进行拷贝，就能够进行watch
 */
const formForWatch: ComputedRef<OrderModel> = computed(() => JSON.parse(JSON.stringify(order.value)))

// 搜索备选
const allConsumers = ref([] as ContactModel[])
const allItems = ref([] as MaterialModel[])

// 用户选择
const pickingConsumer = ref(false)
function onPickConsumer() {
  pickingConsumer.value = true
}

// 批次切换
const pickingBatch = ref(false)
const inputBatch = ref(null as any)
const inputBatchVal = ref(0)
function onChangeBatch() {
  inputBatchVal.value = order.value.batch
  pickingBatch.value = true
  setTimeout(() => {
    inputBatch.value.focus()
    inputBatch.value.select()
  })
}
function onChangeBatchConfirm() {
  order.value.batch = inputBatchVal.value
  pickingBatch.value = true
}

async function onChangeDate() {
  const d = await pickTime(order.value.date)
  if (d) {
    order.value.date = d
  }
}

onMounted(async () => {
  const s_copyFromId = route.query.copy as string | undefined
  const s_orderId = route.query.id as string | undefined
  const s_userId = route.query.user as string | undefined

  if (s_copyFromId) {
    editMode.value = Mode.Copy
  }
  else if (s_orderId) {
    editMode.value = Mode.Edit
  }
  else if (s_userId) {
    editMode.value = Mode.FillUser
  }

  const [consumers, items] = await Promise.all([
    Api.Contact.getAll(),
    Api.Material.getAll(),
  ])

  allConsumers.value = consumers
  allItems.value = items

  if (editMode.value === Mode.Copy) {
    await initFromExist(Number.parseInt(s_copyFromId!))
  }
  else if (editMode.value === Mode.Edit) {
    await initEditExist(Number.parseInt(s_orderId!))
  }
  else if (editMode.value === Mode.FillUser) {
    await initFillUser(Number.parseInt(s_userId!))
  }

  // 全新订单弹出选择用户
  setTimeout(() => {
    if (isNew.value && !order.value.consumer) {
      pickingConsumer.value = true
    }
  }, 600)

  // loading.value = false

  // DEBUG: 显示当前订单
  // setTimeout(() => {
  //   console.log('订单', order)
  // }, 1000)
})

// 初始化：复制订单
async function initFromExist(orderId: number) {
  const _order = await Api.Order.get(orderId)

  order.value = lodash.cloneDeep(_order)

  order.value.date = new Date()
  order.value.invalid = false
  order.value.settled = false
}

// 初始化：编辑订单
async function initEditExist(orderId: number) {
  const _order = await Api.Order.get(orderId)

  order.value = lodash.cloneDeep(_order)
  originOrder.value = lodash.cloneDeep(_order)
}

async function initFillUser(userId: number) {
  order.value.consumer = allConsumers.value.find(x => x.id === userId)
}

watch(formForWatch, async (val: OrderModel, oldVal: OrderModel) => {
  /**
   * 切换用户的时候，批次的计算规则：
   * 1. 新订单：获取用户最大批次+1
   * 2. 编辑订单：
   *    - 如果切换到新用户，沿用创建新订单的规则
   *    - 如果切换回原来的用户，切换回原来的批次
   */
  if (val.consumer && val.consumer.id !== oldVal.consumer?.id) {
    if (!isNew.value && val.consumer?.id === originOrder.value.consumer?.id) {
      // console.log('还原');
      // console.log();
      order.value.batch = originOrder.value.batch
    }
    else {
      console.log('batch计算')
      Api.Order.getNewOrderBatchOfConsumer(val.consumer.id)
        .then((res) => {
          order.value.batch = res
        })
    }
  }

  // 销售单: 逐行比较
  for (let i = 0; i < val.items.length; i++) {
    const row = val.items[i]
    const rowOld = oldVal.items[i]
    const rowReal = order.value.items[i]
    // 增删的行跳过操作
    if (row === undefined || rowOld === undefined)
      continue

    // 金额自动计算
    if (row.quantity !== rowOld.quantity || row.unitPrice !== rowOld.unitPrice) {
      rowReal.autoAmount()
    }

    // 数量去除首 0
    if (row.quantity !== rowOld.quantity && row.quantity === 0) {
      rowReal.quantity = Number.parseInt(row.quantity.toString())
    }
  }
}, {
  immediate: false,
})

async function onSave() {
  if (!order.value.consumer) {
    showFailToast('请选择联系人')
    return
  }
  if (!order.value.items.length) {
    showFailToast('不允许保存空订单')
    return
  }
  if (order.value.items.some(x => x.material!.id < 0)) {
    showFailToast('请选择商品')
    return
  }
  const itemsLen = order.value.items.length
  const itemSpecies = (new Set(order.value.items.map(x => x.material!.id))).size
  if (itemsLen !== itemSpecies) {
    showFailToast('同种商品不允许分成多个条目')
    return
  }

  // 唯一性检验：用户，批次
  const page = await OrderApi.getPaged(1, 1000000, {
    consumer: order.value.consumer?.id.toString(),
  })
  const orders = page.objects
  const exist = orders.find((x) => {
    return x.consumer?.id === order.value.consumer?.id
      && x.batch === order.value.batch
  })
  // 创建冲突 || 覆盖冲突 （要排除编辑原本订单不能保存）
  const isOrigin = originOrder.value.consumer?.id === order.value.consumer.id
    && originOrder.value.batch === order.value.batch
  if (exist) {
    if (isNew.value || (!isNew.value && !isOrigin)) {
      showFailToast(`${order.value.consumer.name}的 第${order.value.batch}单 已经存在`)
      return
    }
  }

  // 运费输入空
  if (Number.isNaN(order.value.fare)) {
    order.value.fare = 0
  }

  save()
}

async function save() {
  if (isNew.value) {
    const ok = await Api.Order.add(order.value)
    if (ok) {
      const page = await OrderApi.getPaged(1, 1000000, {
        consumer: order.value.consumer?.id.toString(),
      })
      const orders = page.objects
      const _order = orders.find((x) => {
        return x.consumer?.id === order.value.consumer?.id
          && x.batch === order.value.batch
      })
      if (_order) {
        router.replace(`/orders/detail?id=${_order.id}`)
        // router.back()
      }
    }
    else {
      showFailToast('保存失败，请联系管理员')
    }
  }
  else {
    const ok = await Api.Order.update(order.value.id, order.value)
    if (ok) {
      // 返回到之前的详情页面
      router.back()
    }
    else {
      showFailToast('保存失败，请联系管理员')
    }
  }
}


// setInterval(() => {
//   console.log(order.value.batch);
// }, 2000)
</script>

<template>
  <div pb14>
    <ContactPick
      v-model="pickingConsumer"
      v-model:consumer="order.consumer"
    />

    <Dialog
      v-model:show="pickingBatch"
      title="批次"
      width="80%"
      :show-confirm-button="true"
      :show-cancel-button="true"
      @confirm="onChangeBatchConfirm"
    >
      <input ref="inputBatch" v-model="inputBatchVal" type="number" mb2 w-full b-none bg-light-5 text-center lh-10>
    </Dialog>
    <div px4>
      <div v-if="isNew" style="display: flex; align-items: baseline;">
        <h1 style="margin-right: 1rem;">
          新订单
        </h1>
      </div>
      <div v-else style="display: flex; align-items: baseline;">
        <h1 mr4>
          订单
        </h1>
        <div>
          No.{{ order.serial() }}
        </div>
      </div>
    </div>

    <PairsView
      :pairs="order.consumer ? ([
        ['客户', order.consumer.name, onPickConsumer],
        ['批次', `第 ${order.batch} 单`, onChangeBatch],
        ['时间', Common.timeFormat(order.date), onChangeDate],
      ]) : ([
        ['客户', '（请选择用户）', onPickConsumer],
      ])"
    />

    <div v-if="order.consumer">
      <ItemsEditor :order="order" :editable="true" />

      <DeliveryView :order="order" :editable="true" />

      <Field
        v-model="order.notes"
        label="订单备注"
        placeholder="无备注"
        input-align="right"
      />
    </div>

    <ActionBar>
      <ActionBarButton type="danger" text="放弃" @click="$router.back()" />
      <ActionBarButton :type="isNew ? 'success' : 'primary'" :text="isNew ? '创建' : '保存'" @click="onSave" />
    </ActionBar>
  </div>
</template>

<route lang="yaml">
meta:
  title: 订单编辑
</route>
